package com.aizhixin.lab.course.template.service;

import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.common.core.*;
import com.aizhixin.lab.common.domain.PageDomain;
import com.aizhixin.lab.common.dto.SortDTO;
import com.aizhixin.lab.common.utils.PageJdbcUtil;
import com.aizhixin.lab.company.entity.User;
import com.aizhixin.lab.company.repository.UserRepository;
import com.aizhixin.lab.course.course.domain.CourseDomain;
import com.aizhixin.lab.course.template.domain.TemplateDomain;
import com.aizhixin.lab.course.template.domain.TemplateFileDomain;
import com.aizhixin.lab.course.template.domain.TemplateProfDomain;
import com.aizhixin.lab.course.template.dto.TemplateDTO;
import com.aizhixin.lab.course.template.dto.TemplateFileDTO;
import com.aizhixin.lab.course.template.dto.TemplateProfDTO;
import com.aizhixin.lab.course.template.entity.Template;
import com.aizhixin.lab.course.template.entity.TemplateFile;
import com.aizhixin.lab.course.template.entity.TemplateProf;
import com.aizhixin.lab.course.template.repository.TemplateFileRepository;
import com.aizhixin.lab.course.template.repository.TemplateProfRepository;
import com.aizhixin.lab.course.template.repository.TemplateRepository;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

@Slf4j
@Service
@Transactional
public class TemplateService {
    @Autowired
    private TemplateRepository templateRepository;
    @Autowired
    private TemplateFileRepository templateFileRepository;
    @Autowired
    private TemplateProfRepository templateProfRepository;
    @Autowired
    private PageJdbcUtil pageJdbcUtil;
    @Autowired
    private UserRepository userRepository;
    RowMapper<Template> templateRowMapper = new RowMapper<Template>() {

        @Override
        public Template mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            // TODO Auto-generated method stub
            Template domain = new Template();
            domain.setId(rs.getLong("id"));
            domain.setName(rs.getString("name"));
            domain.setType(rs.getInt("type"));
            domain.setClassHour(rs.getInt("class_hour"));
            domain.setCountChapter(rs.getInt("count_chapter"));
            domain.setCountSection(rs.getInt("count_section"));
            domain.setImage(rs.getString("image"));
            domain.setIntro(rs.getString("intro"));
            domain.setIsPublish(rs.getBoolean("is_publish"));
            domain.setCreatedBy(rs.getLong("created_by"));
            return domain;
        }
    };

    public PageData<TemplateDomain> getPublishedList(String name, Integer type, Long profId, Integer pageNumber, Integer pageSize, AccountDTO account,Integer section) {
//        List<Long> createdBys=new ArrayList<>();
//        createdBys.add(account.getId());
//        createdBys.add(4L);
        String sql = "select distinct ct.id, ct.name, ct.type, ct.class_hour, ct.count_chapter, ct.count_section, ct.image, ct.intro, ct.is_publish, ct.created_by, ct.created_date, ct.last_modified_by, ct.last_modified_date, ct.delete_flag from c_template ct left join c_template_prof ctp on ct.id=ctp.template_id where ct.delete_flag=0 and ct.is_publish=1 ";
        String countSql = "select count(distinct ct.id) from c_template ct left join c_template_prof ctp on ct.id=ctp.template_id where ct.delete_flag=0 and ct.is_publish=1";
        if (!StringUtils.isEmpty(name)) {
            sql += " and ct.name like '%" + name + "%'";
            countSql += " and ct.name like '%" + name + "%'";
        }
        if (type != null && type != 0) {
            sql += " and ct.type=" + type;
            countSql += " and ct.type=" + type;
        }
        if (profId != null && profId != 0L) {
            sql += " and ctp.prof_id=" + profId;
            countSql += " and ctp.prof_id=" + profId;
        }
        if (section!=null){
            sql+=" and ct.count_section<>0";
            countSql+=" and ct.count_section<>0";
        }

        List<SortDTO> sort = new ArrayList<SortDTO>();
        SortDTO dto = new SortDTO();
        dto = new SortDTO();
        dto.setKey("ct.id");
        dto.setAsc(false);
        sort.add(dto);
        Map<String, Object> pageInfor = pageJdbcUtil.getPageInfor(pageSize, pageNumber, templateRowMapper, sort, sql, countSql);
        List<Template> list = (List<Template>) pageInfor.get(ApiReturnConstants.DATA);
        List<TemplateDomain> copyList = new ArrayList<TemplateDomain>();
        if (null != list && list.size() > 0) {
            String templateIds = "";
            for (Template template : list) {
                if (StringUtils.isEmpty(templateIds)) {
                    templateIds = "" + template.getId();
                } else {
                    templateIds += "," + template.getId();
                }
                TemplateDomain domain = new TemplateDomain();
                BeanUtils.copyProperties(template, domain);
                User one = userRepository.findOne(template.getCreatedBy());
                if (!Objects.isNull(one)){
                    domain.setUserName(one.getName());
                }
                copyList.add(domain);
            }
            List<TemplateDomain> countList = getTemplateVmCount(templateIds);
            HashMap<Long, Integer> countMap = new HashMap<Long, Integer>();
            for (TemplateDomain domain : countList) {
                countMap.put(domain.getId(), domain.getCountVm());
            }

            for (TemplateDomain domain : copyList) {
                if (null != countMap.get(domain.getId())) {
                    domain.setCountVm(countMap.get(domain.getId()));
                }
            }

        }
        List<TemplateDomain> templateList1 = new ArrayList<>();
        copyList.forEach(domain -> {
            String sql1 = "SELECT COUNT(DISTINCT c.parent_id) FROM c_template_chapter c WHERE c.template_id=" + domain.getId() + " AND c.delete_flag=0 AND c.parent_id IS NOT NULL";
            Integer countInt1 = pageJdbcUtil.getCountInt(sql1);
            domain.setCountSection(domain.getCountSection() + domain.getCountChapter() - countInt1);
            templateList1.add(domain);
        });
        PageData<TemplateDomain> pageData = new PageData<>();
        pageData.setData(templateList1);
        pageData.setPage((PageDomain) pageInfor.get(ApiReturnConstants.PAGE));
        return pageData;
    }


    RowMapper<TemplateDomain> rm1 = new RowMapper<TemplateDomain>() {

        @Override
        public TemplateDomain mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            // TODO Auto-generated method stub
            TemplateDomain domain = new TemplateDomain();
            domain.setId(rs.getLong("template_id"));
            domain.setCountVm(rs.getInt("vm_count"));
            return domain;
        }
    };

    public List<TemplateDomain> getTemplateVmCount(String templateIds) {
        String sql = "select cc.template_id,COUNT(*) as vm_count from `c_template_chapter` cc where cc.template_id in (" + templateIds + ") and cc.vm_num > 0 and cc.delete_flag = 0 GROUP BY cc.template_id";
        return pageJdbcUtil.getInfo(sql, rm1);
    }

    public PageData<Template> getList(String name, Integer type, Integer isPublish, Long profId, Integer pageNumber, Integer pageSize, Long createdBy, Integer deleteFlag) {
        String sql = "select distinct ct.id, ct.name, ct.type, ct.class_hour, ct.count_chapter, ct.count_section, ct.image, ct.intro, ct.is_publish, ct.created_by, ct.created_date, ct.last_modified_by, ct.last_modified_date, ct.delete_flag from c_template ct left join c_template_prof ctp on ct.id=ctp.template_id ";
        String countSql = "select count(distinct ct.id) from c_template ct left join c_template_prof ctp on ct.id=ctp.template_id ";
        if (deleteFlag == null || deleteFlag == 0) {
            sql += "where ct.delete_flag=0 ";
            countSql += "where ct.delete_flag=0";
        } else {
            sql += "where ct.delete_flag=1 ";
            countSql += "where ct.delete_flag=1";
        }
        if (!StringUtils.isEmpty(name)) {
            sql += " and ct.name like '%" + name + "%'";
            countSql += " and ct.name like '%" + name + "%'";
        }
        if (type != null && type != 0) {
            sql += " and ct.type=" + type;
            countSql += " and ct.type=" + type;
        }
        if (profId != null && profId != 0L) {
            sql += " and ctp.prof_id=" + profId;
            countSql += " and ctp.prof_id=" + profId;
        }
        if (isPublish != null && isPublish.intValue() > 0) {
            Integer isPub = isPublish == 10 ? 0 : 1;
            sql += " and ct.is_publish=" + isPub;
            countSql += " and ct.is_publish=" + isPub;
        }
        if (createdBy != null && createdBy != 0L) {
            sql += " and ct.created_by=" + createdBy;
            countSql += " and ct.created_by=" + createdBy;
        }

        List<SortDTO> sort = new ArrayList<SortDTO>();
        SortDTO dto = new SortDTO();
        dto = new SortDTO();
        dto.setKey("ct.id");
        dto.setAsc(false);
        sort.add(dto);
        Map<String, Object> pageInfor = pageJdbcUtil.getPageInfor(pageSize, pageNumber, templateRowMapper, sort, sql, countSql);
        List<Template> templateList = (List<Template>) pageInfor.get(ApiReturnConstants.DATA);
        List<Template> templateList1 = new ArrayList<>();
        templateList.forEach(domain -> {
            String sql1 = "SELECT COUNT(DISTINCT c.parent_id) FROM c_template_chapter c WHERE c.template_id=" + domain.getId() + " AND c.delete_flag=0 AND c.parent_id IS NOT NULL";
            Integer countInt1 = pageJdbcUtil.getCountInt(sql1);
            domain.setCountSection(domain.getCountSection() + domain.getCountChapter() - countInt1);
            templateList1.add(domain);
        });


//        Pageable pageable = PageUtil.createRequestAndSortType(pageNumber, pageSize, "desc", "id");
//        Page<Template> page;
//        if (type != null && type > 0) {
//            if (isPublish != null && isPublish.intValue() > 0) {
//                Boolean isPub = isPublish == 10 ? false : true;
//                if (createdBy != null) {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByTypeAndDeleteFlagAndIsPublishAndCreatedBy(pageable, type, DataValidity.VALID.getState(), isPub,createdBy);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByTypeAndDeleteFlagAndIsPublishAndNameLikeIgnoreCaseAndCreatedBy(pageable, type, DataValidity.VALID.getState(), isPub, name,createdBy);
//                    }
//                } else {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByTypeAndDeleteFlagAndIsPublish(pageable, type, DataValidity.VALID.getState(), isPub);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByTypeAndDeleteFlagAndIsPublishAndNameLikeIgnoreCase(pageable, type, DataValidity.VALID.getState(), isPub, name);
//                    }
//                }
//            } else {
//                if (createdBy != null) {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByTypeAndDeleteFlagAndCreatedBy(pageable, type, DataValidity.VALID.getState(),createdBy);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByTypeAndDeleteFlagAndNameLikeIgnoreCaseAndCreatedBy(pageable, type, DataValidity.VALID.getState(), name,createdBy);
//                    }
//                } else {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByTypeAndDeleteFlag(pageable, type, DataValidity.VALID.getState());
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByTypeAndDeleteFlagAndNameLikeIgnoreCase(pageable, type, DataValidity.VALID.getState(), name);
//                    }
//                }
//            }
//        } else {
//            if (isPublish != null && isPublish.intValue() > 0) {
//                Boolean isPub = isPublish == 10 ? false : true;
//                if (createdBy != null) {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByDeleteFlagAndIsPublishAndCreatedBy(pageable, DataValidity.VALID.getState(), isPub,createdBy);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByDeleteFlagAndIsPublishAndNameLikeIgnoreCaseAndCreatedBy(pageable, DataValidity.VALID.getState(), isPub, name,createdBy);
//                    }
//                } else {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByDeleteFlagAndIsPublish(pageable, DataValidity.VALID.getState(), isPub);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByDeleteFlagAndIsPublishAndNameLikeIgnoreCase(pageable, DataValidity.VALID.getState(), isPub, name);
//                    }
//                }
//            } else {
//                if (createdBy != null) {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByDeleteFlagAndCreatedBy(pageable, DataValidity.VALID.getState(),createdBy);
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByDeleteFlagAndNameLikeIgnoreCaseAndCreatedBy(pageable, DataValidity.VALID.getState(), name,createdBy);
//                    }
//                } else {
//                    if (StringUtils.isEmpty(name)) {
//                        page = templateRepository.findByDeleteFlag(pageable, DataValidity.VALID.getState());
//                    } else {
//                        name = "%" + name + "%";
//                        page = templateRepository.findByDeleteFlagAndNameLikeIgnoreCase(pageable, DataValidity.VALID.getState(), name);
//                    }
//                }
//            }
//        }
//        PageDomain pageDomain = new PageDomain();
//        pageDomain.setPageSize(page.getSize());
//        pageDomain.setPageNumber(page.getNumber());
//        pageDomain.setTotalElements(page.getTotalElements());
//        pageDomain.setTotalPages(page.getTotalPages());

        PageData<Template> pageData = new PageData<>();
        pageData.setData(templateList1);
        pageData.setPage((PageDomain) pageInfor.get(ApiReturnConstants.PAGE));
        return pageData;
    }

    public TemplateDomain getTemplate(Long templateId) {
        TemplateDomain domain = new TemplateDomain();
        Template template = templateRepository.findByIdAndDeleteFlag(templateId, DataValidity.VALID.getState());

        if (template != null) {
            BeanUtils.copyProperties(template, domain);
            String sql = "SELECT COUNT(DISTINCT c.parent_id) FROM c_template_chapter c WHERE c.template_id=" + templateId + " AND c.delete_flag=0 AND c.parent_id IS NOT NULL";
            Integer countInt1 = pageJdbcUtil.getCountInt(sql);
            domain.setCountSection(domain.getCountSection() + domain.getCountChapter() - countInt1);
            List<TemplateFile> files = templateFileRepository.findByTemplateId(templateId);
            if (files != null && !files.isEmpty()) {
                List<TemplateFileDomain> list = new ArrayList<>();
                for (TemplateFile item : files) {
                    TemplateFileDomain d = new TemplateFileDomain();
                    BeanUtils.copyProperties(item, d);
                    list.add(d);
                }
                domain.setFileList(list);
            }
            List<TemplateProf> profs = templateProfRepository.findByTemplateId(templateId);
            if (profs != null && !profs.isEmpty()) {
                List<TemplateProfDomain> list = new ArrayList<>();
                for (TemplateProf item : profs) {
                    TemplateProfDomain d = new TemplateProfDomain();
                    BeanUtils.copyProperties(item, d);
                    list.add(d);
                }
                domain.setProfList(list);
            }
        }

        return domain;
    }

    public Map<String, Object> publish(Long templateId) {
        Map<String, Object> result = new HashMap<>();
        Template template = templateRepository.findByIdAndDeleteFlag(templateId, DataValidity.VALID.getState());
        if (template != null) {
            template.setIsPublish(!template.getIsPublish());
            templateRepository.save(template);
            result.put(ApiReturnConstants.SUCCESS, true);
        } else {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.ERROR, "没有课程信息");
        }
        return result;
    }

    public Map<String, Object> save(TemplateDTO dto, AccountDTO accountDTO) {
        Map<String, Object> result = new HashMap<>();
        Template template = null;
        if (dto.getId() != null && dto.getId().longValue() > 0) {
            templateFileRepository.deleteByTemplateId(dto.getId());
            templateProfRepository.deleteByTemplateId(dto.getId());
            template = templateRepository.findOne(dto.getId());
        }
        if (template == null) {
            template = new Template();
            template.setCountChapter(0);
            template.setCountSection(0);
            template.setIsPublish(false);
            if (accountDTO.getRole().equals(UserInforCore.ROLE_SUPER_ADMIN) || accountDTO.getRole().equals(UserInforCore.ROLE_ADMIN)) {
                template.setCreatedBy(4L);
            } else {
                template.setCreatedBy(accountDTO.getId());
            }
        }
        BeanUtils.copyProperties(dto, template);
        template = templateRepository.save(template);
        if (dto.getFileList() != null && !dto.getFileList().isEmpty()) {
            List<TemplateFile> list = new ArrayList<>();
            for (TemplateFileDTO item : dto.getFileList()) {
                TemplateFile file = new TemplateFile();
                file.setTemplateId(template.getId());
                file.setName(item.getName());
                file.setFileUrl(item.getFileUrl());
                file.setFileKey(item.getFileKey());
                list.add(file);
            }
            templateFileRepository.save(list);
        }
        if (dto.getProfList() != null && !dto.getProfList().isEmpty()) {
            List<TemplateProf> list = new ArrayList<>();
            for (TemplateProfDTO item : dto.getProfList()) {
                TemplateProf prof = new TemplateProf();
                prof.setTemplateId(template.getId());
                prof.setProfId(item.getProfId());
                prof.setProfName(item.getProfName());
                list.add(prof);
            }
            templateProfRepository.save(list);
        }
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put("templateId", template.getId());
        return result;
    }

    public Map<String, Object> delete(Long templateId) {
        Map<String, Object> result = new HashMap<>();
        Template template = templateRepository.findByIdAndDeleteFlag(templateId, DataValidity.VALID.getState());
        if (template != null) {
            template.setDeleteFlag(DataValidity.INVALID.getState());
            templateRepository.save(template);
            result.put(ApiReturnConstants.SUCCESS, true);
        } else {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.ERROR, "没有课程信息");
        }
        return result;
    }

    public Boolean isExist(String name) {
        return templateRepository.countByNameAndDeleteFlag(name, DataValidity.VALID.getState()) > 0 ? true : false;
    }
}
